///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
#include <Timer.h>
#include <stdlib.h>

//-----------------------------------------------------------------------------

Timer::Timer()
{
#ifdef WIN32
    QueryPerformanceFrequency(&frequency);
    startCount.QuadPart = 0;
    endCount.QuadPart = 0;
#else
    startCount.tv_sec = startCount.tv_usec = 0;
    endCount.tv_sec = endCount.tv_usec = 0;
#endif

    stopped = 0;
    startTimeInMicroSec = 0;
    endTimeInMicroSec = 0;
}

//-----------------------------------------------------------------------------

Timer::~Timer()
{
}

//-----------------------------------------------------------------------------

void Timer::start()
{
    stopped = 0; // reset stop flag
#ifdef WIN32
    QueryPerformanceCounter(&startCount);
#else
    gettimeofday(&startCount, NULL);
#endif
}

//-----------------------------------------------------------------------------

void Timer::stop()
{
    stopped = 1; // set timer stopped flag

#ifdef WIN32
    QueryPerformanceCounter(&endCount);
#else
    gettimeofday(&endCount, NULL);
#endif
}

//-----------------------------------------------------------------------------

f64 Timer::getElapsedTimeInMicroSec()
{
#ifdef WIN32
    if(!stopped)
        QueryPerformanceCounter(&endCount);

    startTimeInMicroSec = startCount.QuadPart * (1000000.0 / frequency.QuadPart);
    endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
#else
    if(!stopped)
        gettimeofday(&endCount, NULL);

    startTimeInMicroSec = (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
    endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
#endif

    return endTimeInMicroSec - startTimeInMicroSec;
}

//-----------------------------------------------------------------------------

f64 Timer::getElapsedTimeInMilliSec()
{
    return this->getElapsedTimeInMicroSec() * 0.001;
}

//-----------------------------------------------------------------------------

f64 Timer::getElapsedTimeInSec()
{
    return this->getElapsedTimeInMicroSec() * 0.000001;
}

//-----------------------------------------------------------------------------

f64 Timer::getElapsedTime()
{
    return this->getElapsedTimeInSec();
}

//-----------------------------------------------------------------------------

f64	Timer::getStartTimeInSec()
{
	return this->getStartTimeInMicroSec() * 0.000001;
}

//-----------------------------------------------------------------------------

f64	Timer::getStartTimeInMilliSec()
{
	return this->getStartTimeInMicroSec() * 0.001;
}

//-----------------------------------------------------------------------------

f64	Timer::getStartTimeInMicroSec()
{
#ifdef WIN32
    startTimeInMicroSec = startCount.QuadPart * (1000000.0 / frequency.QuadPart);
#else
    startTimeInMicroSec = (startCount.tv_sec * 1000000.0) + startCount.tv_usec;
#endif

    return startTimeInMicroSec;
}

//-----------------------------------------------------------------------------

f64	Timer::getEndTimeInSec()
{
	return this->getEndTimeInMicroSec() * 0.000001;
}

//-----------------------------------------------------------------------------

f64	Timer::getEndTimeInMilliSec()
{
	return this->getEndTimeInMicroSec() * 0.001;
}

//-----------------------------------------------------------------------------

f64	Timer::getEndTimeInMicroSec()
{
#ifdef WIN32
    endTimeInMicroSec = endCount.QuadPart * (1000000.0 / frequency.QuadPart);
#else
    endTimeInMicroSec = (endCount.tv_sec * 1000000.0) + endCount.tv_usec;
#endif

    return endTimeInMicroSec;
}

//-----------------------------------------------------------------------------

void	Timer::sleepTime(u32 sec)
{
	sleepTimeInSec( sec );
}

//-----------------------------------------------------------------------------

void	Timer::sleepTimeInSec(u32 sec)
{
	sleepTimeInMilliSec( sec * 1000 );
}

//-----------------------------------------------------------------------------

void	Timer::sleepTimeInMilliSec(u32 msec)
{
	sleepTimeInMicroSec( msec * 1000 );
}

//-----------------------------------------------------------------------------

void	Timer::sleepTimeInMicroSec(u32 usec)
{
	u32 time = (u32)getElapsedTimeInMicroSec();
	if( (s64)(usec - time) > 100 )
	{
		time = usec - time;
#if	defined(WIN32)
		Sleep( time / 1000 );
#elif	defined(LINUX)
		usleep( time );
#endif
	}
}

//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
